package com.usian.controller;

import com.usian.feign.CarFeign;
import com.usian.feign.ItemServiceFeign;
import com.usian.pojo.TbItem;
import com.usian.utils.CookieUtils;
import com.usian.utils.JsonUtils;
import com.usian.utils.Result;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

@RestController
@RequestMapping("/frontend/cart")
public class CarWebController {

    @Autowired
    CarFeign carFeign;

    @Autowired
    ItemServiceFeign itemServiceFeign;

    //存入cookie的KEY值
    @Value("${CART_COOKIE_KEY}")
    private String CART_COOKIE_KEY;
    //存入cookie的过期时间
    @Value("${CART_COOKIE_EXPIRE}")
    private Integer CART_COOKIE_EXPIRE;

    /**
     * 删除购物车商品信息
     *
     * @param itemId
     * @param userId
     * @param request
     * @param response
     * @return
     */
    @RequestMapping("deleteItemFromCart")
    public Result deleteItemFromCart(String itemId, String userId, HttpServletRequest
            request, HttpServletResponse response) {
        try {
            if (StringUtils.isBlank(userId)) {
                //未登录状态
                //获取cookie中购物车信息
                Map<String, TbItem> cart = this.getCartFromCookie(request);
                //删除购物车指定商品信息
                cart.remove(itemId);
                //删除完成 添加到cookie
                this.addClientCookie(request, response, cart);
                System.out.println("未登录状态删除购物车商品信息");
            } else {
                //已登录状态
                //获取redis中购物车信息
                Map<String, TbItem> cart = this.getCartFromRedis(userId);

               /* lamda表达式方式 map表遍历方式
               cart.forEach((k,v)->{
                    System.out.println(k+"====="+v);
                });*/

              /*map遍历方式
               for (Map.Entry<String,TbItem> map : cart.entrySet()){
                   System.out.println(map.getKey()+"===="+map.getValue());
               }*/

                //删除购物车指定商品信息
                cart.remove(itemId);
                //删除完成 添加到redis缓存
                this.addCartToRedis(userId, cart);
                System.out.println("已登录状态删除购物车商品信息");
            }
            return Result.ok("删除成功");
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error("删除失败");
        }


    }

    /**
     * 修改购物车
     *
     * @param itemId
     * @param userId
     * @param num
     * @param request
     * @param response
     * @return
     */
    @RequestMapping("updateItemNum")
    public Result updateItemNum(String itemId, String userId, Integer
            num, HttpServletRequest request, HttpServletResponse response) {

        try {
            if (StringUtils.isBlank(userId)) {
                //未登录状态下
                //先获取cookie中的购物车信息
                Map<String, TbItem> cart = this.getCartFromCookie(request);
                //获取购物车指定的商品信息
                TbItem item = cart.get(itemId);
                //修改该商品数量
                item.setNum(num);
                //重新放入购物车
                cart.put(itemId, item);
                //将修改后的购物车放入cookie
                this.addClientCookie(request, response, cart);
                System.out.println("未登录状态下修改");
            } else {
                //已登录状态下
                //获取redis的购物车信息
                Map<String, TbItem> cart = this.getCartFromRedis(userId);
                //查到购物车中指定的商品信息
                TbItem item = cart.get(itemId);
                //修改数量
                item.setNum(num);
                //重新放入购物车
                cart.put(itemId, item);
                //把购物车写到redis
                this.addCartToRedis(userId, cart);
                System.out.println("已登录状态下修改");
            }
            return Result.ok("修改成功");
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error("修改失败");
        }

    }

    /**
     * 查看购物车
     *
     * @param userId
     * @param request
     * @param response
     * @return
     */
    @RequestMapping("showCart")
    public Result showCart(String userId, HttpServletRequest request, HttpServletResponse response) {
        try {
            //未登录状态下
            if (StringUtils.isBlank(userId)) {
                //未登录状态下
                List<TbItem> list = new ArrayList<>();
                Map<String, TbItem> map = this.getCartFromCookie(request);
                Set<String> set = map.keySet();
                for (String key : set) {
                    list.add(map.get(key));
                }
                System.out.println("未登录状态下查询");
                return Result.ok(list);
            } else {
                //已登陆状态下
                //获取cookie中的购物车,如果cookie为空则不需要同步
                Map<String, TbItem> cookieMap = this.getCartFromCookie(request);
                if (cookieMap != null && cookieMap.size() > 0){
                    //如果cookie里有数据，取出数据放到redis，相同数据数量相加
                    Map<String, TbItem> redisMap = this.getCartFromRedis(userId);
                    Map<String,TbItem> map = new HashMap<>();
                    if (redisMap != null && redisMap.size() > 0){
                        //redis不为空
                        Set<String> cookieSet = cookieMap.keySet();
                        Set<String> redisSet = redisMap.keySet();
                        for (String redisKey : redisSet) {
                            for (String cookieKey : cookieSet) {
                                if (redisKey.equals(cookieKey)){
                                    //如果是相同的数据
                                    TbItem item = cookieMap.get(cookieKey);
                                    TbItem tbItem = redisMap.get(redisKey);
                                    tbItem.setNum(item.getNum()+tbItem.getNum());
                                    map.put(redisKey,tbItem);
                                }else {
                                    //不是相同数据
                                    TbItem item = cookieMap.get(cookieKey);
                                    map.put(cookieKey,item);
                                }
                            }
                        }
                    }else {
                        //redis为空
                        Set<String> cookieSet = cookieMap.keySet();
                        for (String cookieKey : cookieSet) {
                            TbItem item = cookieMap.get(cookieKey);
                            map.put(cookieKey,item);
                        }
                    }
                    //将准备好的购物车存入redis
                    this.addCartToRedis(userId, map);
                    //删除cookie中的购物车
                    this.deleteCokie(request, response);
                }

                //已登陆状态下
                List<TbItem> list = new ArrayList<>();
                //从redis中获取购物车信息
                Map<String, TbItem> redisMap = this.getCartFromRedis(userId);
                Set<String> redisKeys = redisMap.keySet();
                //查询同步后的所有购物车商品信息
                for (String redisKey : redisKeys) {
                    list.add(redisMap.get(redisKey));
                }
                System.out.println("已登陆状态下查询");
                return Result.ok(list);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error("error");
        }
    }


    /**
     * 将商品加入购物车
     *
     * @param itemId
     * @param userId
     * @param num
     * @param request
     * @param response
     * @return
     */
    @RequestMapping("addItem")
    public Result addItem(Long itemId, String userId, @RequestParam(defaultValue = "1") Integer num,
                          HttpServletRequest request, HttpServletResponse response) {
        try {
            //未登录状态下
            if (StringUtils.isBlank(userId)) {
                //第一步从cookie中查询商品列表
                Map cart = getCartFromCookie(request);
                //添加商品到购物车
                this.addItemToCart(cart, itemId, num);
                //把购物车列表写入cookie
                addClientCookie(request, response, cart);
                return Result.ok("OK");
            } else {
                //以登陆状态下
                //从redis中查询商品列表
                Map cart = getCartFromRedis(userId);
                //将商品添加到购物车中
                this.addItemToCart(cart, itemId, num);
                //将购物车缓存到redis中
                Boolean addCartToRedis = this.addCartToRedis(userId, cart);
                if (addCartToRedis) {
                    return Result.ok("OK");
                }
                return Result.error("添加购物车失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error("添加购物车失败");
        }
    }

    /**
     * 从redis中查询购物车
     *
     * @param userId
     */
    private Map getCartFromRedis(String userId) {
        Map cart = carFeign.selectCartByUserId(userId);
        if (cart != null && cart.size() > 0) {
            return cart;
        }
        return new HashMap();
    }

    /**
     * 把购物车信息写入redis
     *
     * @param userId
     * @param cart
     */
    private Boolean addCartToRedis(String userId, Map cart) {
        return carFeign.insertCart(userId, cart);
    }

    /**
     * 把购车商品列表写入cookie
     *
     * @param request
     * @param response
     * @param cart
     */
    private void addClientCookie(HttpServletRequest request, HttpServletResponse response, Map cart) {
        String cartJson = JsonUtils.objectToJson(cart);
        CookieUtils.setCookie(request, response, this.CART_COOKIE_KEY, cartJson, this.CART_COOKIE_EXPIRE, true);

    }

    /**
     * 删除cookie中的购物车
     *
     * @param request
     * @param response
     */
    public void deleteCokie(HttpServletRequest request, HttpServletResponse response){
        CookieUtils.deleteCookie(request, response, this.CART_COOKIE_KEY);
        System.out.println("清空cookie中的购物车");
    }

    /**
     * 将商品添加到购物车中
     *
     * @param cart
     * @param itemId
     * @param num
     */
    private void addItemToCart(Map cart, Long itemId, Integer num) {
        //从购物车中获取商品
        TbItem item = (TbItem) cart.get(itemId.toString());
        //商品列表中存在商品，商品数量相加
        if (item != null) {
            item.setNum(item.getNum() + num);
        } else {
            //商品列表中不存在该商品，根据商品id查询商品信息并添加到购车列表
            item = itemServiceFeign.selectItemInfo(itemId);
            item.setNum(num);
        }
        //将商品信息添加到购物车
        cart.put(itemId.toString(), item);
    }

    /**
     * 从cookie获取购物车
     *
     * @param request
     * @return
     */
    private Map getCartFromCookie(HttpServletRequest request) {
        String cartJson = CookieUtils.getCookieValue(request, this.CART_COOKIE_KEY, true);

        if (StringUtils.isNotBlank(cartJson)) {
            //购物车已存在
            return JsonUtils.jsonToMap(cartJson, TbItem.class);
        }
        //购物车不存在
        return new HashMap<>();
    }


}
